import 'dart:async';

import 'package:camerawesome/camerawesome_plugin.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_styled_toast/flutter_styled_toast.dart';
import 'package:get/get.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:share_fit/app/controllers/base/base_controller.dart';
import 'package:share_fit/app/helper/ext/tr_ext.dart';
import 'package:share_fit/app/tools/log_utils.dart';
import 'package:share_fit/app/ute/uteped_const.dart';
import 'package:share_fit/generated/locales.g.dart';

import 'remote_camera_state.dart';

class RemoteCameraLogic extends BaseController {
  final RemoteCameraState state = RemoteCameraState();

  static const methodSetCameraStatus = "setCameraStatus";
  static const statusIcon = 0;
  static const statusOpen = 1;
  static const statusClose = 2;

  CameraState? cameraState;

  Timer? _timer;
  int _countDown = 3;

  void _reportCameraStatus(status) {
    vRemoteReqAsync(methodSetCameraStatus, {UTEPedConst.keyStatus: status});
  }

  @override
  Future<void> onInit() async {
    super.onInit();
    var granted = await Permission.camera.isGranted;
    if (!granted) {
      granted = await Permission.camera.request().isGranted;
      if (!granted) {
        showPermissionDialog(LocaleKeys.contact_permission_tips.ts);
      }
    }

    granted = await Permission.mediaLibrary.isGranted;
    if (!granted) {
      await Permission.mediaLibrary.request();
    }

    granted = await Permission.accessMediaLocation.isGranted;
    if (!granted) {
      await Permission.accessMediaLocation.request();
    }

    granted = await Permission.photos.isGranted;
    if (!granted) {
      await Permission.photos.request();
    }
  }

  @override
  String getRemotePath() {
    return UTEPedConst.pathDevice;
  }

  @override
  String getStoragePath() {
    return UTEPedConst.pathDevice;
  }

  @override
  void initState() {
    _reportCameraStatus(statusIcon);
  }

  @override
  void onReady() {
    super.onReady();
    _reportCameraStatus(statusOpen);
  }

  bool isTakePhoto = false;
  @override
  void onRemoteEvent(event, method) {
    if (method == UTEPedConst.methodCameraControl) {
      if (event[UTEPedConst.keyValue] == UTEPedConst.closeCamera) {
        Get.back();
      } else if (event[UTEPedConst.keyValue] == UTEPedConst.photograph) {
        if(isTakePhoto) {
          return;
        }
        isTakePhoto = true;
        _showCountDown();
        _timer = Timer.periodic(const Duration(milliseconds: 1500), (timer) {
          _countDown--;
          if (_countDown <= 0) {
            isTakePhoto = false;
            _timer?.cancel();
            _countDown = 3;
            _takePhoto();
            update();
          } else {
            _showCountDown();
          }
        });
      }
    }
  }

  void _showCountDown() {
    showToastWidget(
      Center(
        child: Text('$_countDown', style: TextStyle(
            fontSize: 290.sp,
            color: Colors.white
        ),),
      ),
      context: Get.overlayContext!,
      isIgnoring: false,
      position: StyledToastPosition.center,
      duration: const Duration(seconds: 1),
      animation: StyledToastAnimation.scale,
      reverseAnimation: StyledToastAnimation.fade,
      animDuration: const Duration(milliseconds: 200),
      curve: Curves.elasticOut,
      reverseCurve: Curves.linear,
    );
  }

  void _takePhoto() {
    HapticFeedback.selectionClick();

    cameraState?.when(
      onPhotoMode: (photoState) => photoState.takePhoto(
          onPhoto: (value) => {
                value.when(
                  single: (single) {
                    logger.d('single: ${single.file?.path}');
                    ImageGallerySaver.saveFile(single.file!.path, isReturnPathOfIOS: true).then((value) => {logger.d(value)});
                  },
                  multiple: (multiple) {
                    multiple.fileBySensor.forEach((key, value) {
                      logger.d('multiple file taken: $key ${value?.path}');
                    });
                  },
                )
              }),
      onVideoMode: (videoState) => videoState.startRecording(),
      onVideoRecordingMode: (videoState) => videoState.stopRecording(),
    );
  }

  void onDidPop(bool didPop) {
    if (!didPop) {
      Get.back();
      _reportCameraStatus(statusClose);
      _timer?.cancel();
      _countDown = 4;
      isTakePhoto = false;
    }
  }

  void setCameraState(CameraState cameraState) {
    this.cameraState = cameraState;
  }

  @override
  void onClose() {
    super.onClose();
    _timer?.cancel();
    _countDown = 4;
    isTakePhoto = false;
  }
}
